package org.jeecg.common.util;

import cn.hutool.core.codec.Base64;
import lombok.extern.log4j.Log4j2;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;

@Log4j2
public class PdfUtil {
    /**
     * 将网络图片编码为base64（使用的是hutool包下的base64进行编码）
     *
     * @param urlPath
     * @return
     * @throws
     */
    public static String encodeImageToBase64(String urlPath) throws Exception {
        InputStream inStream = null;
        String base64 = "";
        try {
            URL url = new URL(urlPath);
            //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
            log.info("图片的url路径为:" + url.toString());
            //打开链接
            HttpURLConnection conn = null;;
            conn = (HttpURLConnection) url.openConnection();
            //设置请求方式为"GET"
            conn.setRequestMethod("GET");
            //超时响应时间为5秒
            conn.setConnectTimeout(5 * 1000);
            //通过输入流获取图片数据
            inStream = conn.getInputStream();

            //对字节数组Base64编码
            base64 = Base64.encode(inStream);
            base64 = base64.replaceAll("\r\n",""); //替换空格
            //base64 = base64.replaceAll("\\+","%2B");   //替换 + 号
            //log.info("网络文件[{}]编码成base64字符串:[{}]" + base64);
            return base64;      //返回Base64编码过的字节数组字符串
        } catch (IOException e) {
            log.error("图片获取失败"+e.getMessage());
            throw new Exception("图片获取失败");
        } finally {
            try {
                //关闭输入流
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 将base64编码转换成PDF
     *
     * @param base64String 1.使用BASE64Decoder对编码的字符串解码成字节数组
     *                     2.使用底层输入流ByteArrayInputStream对象从字节数组中获取数据；
     *                     3.建立从底层输入流中读取数据的BufferedInputStream缓冲输出流对象；
     *                     4.使用BufferedOutputStream和FileOutputSteam输出数据到指定的文件中
     */
    public static void base64StringToPDF(String base64String, File file) {
        BASE64Decoder decoder = new BASE64Decoder();
        BufferedInputStream bin = null;
        FileOutputStream fout = null;
        BufferedOutputStream bout = null;
        try {
            //将base64编码的字符串解码成字节数组
            byte[] bytes = decoder.decodeBuffer(base64String);
            //创建一个将bytes作为其缓冲区的ByteArrayInputStream对象
            ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
            //创建从底层输入流中读取数据的缓冲输入流对象
            bin = new BufferedInputStream(bais);
            //创建到指定文件的输出流
            fout = new FileOutputStream(file);
            //为文件输出流对接缓冲输出流对象
            bout = new BufferedOutputStream(fout);

            byte[] buffers = new byte[1024];
            int len = bin.read(buffers);
            while (len != -1) {
                bout.write(buffers, 0, len);
                len = bin.read(buffers);
            }
            //刷新此输出流并强制写出所有缓冲的输出字节，必须这行代码，否则有可能有问题
            bout.flush();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bout.close();
                fout.close();
                bin.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * PDF转换为Base64编码
     *
     * @param file
     * @return
     */
    public static String pdfToBase64(File file) {
        BASE64Encoder encoder = new BASE64Encoder();
        FileInputStream fin = null;
        BufferedInputStream bin = null;
        ByteArrayOutputStream baos = null;
        BufferedOutputStream bout = null;
        try {
            fin = new FileInputStream(file);
            bin = new BufferedInputStream(fin);
            baos = new ByteArrayOutputStream();
            bout = new BufferedOutputStream(baos);
            byte[] buffer = new byte[1024];
            int len = bin.read(buffer);
            while (len != -1) {
                bout.write(buffer, 0, len);
                len = bin.read(buffer);
            }
            //刷新此输出流并强制写出所有缓冲的输出字节
            bout.flush();
            byte[] bytes = baos.toByteArray();
            return encoder.encodeBuffer(bytes).trim();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fin.close();
                bin.close();
                baos.close();
                bout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }


    /**
     *备用方法：url转base64（使用的是sun下的Base64包进行编码）
     */
    public static String encodeImageToBase64Bak(String urlPath) throws Exception {
        InputStream inStream = null;
        ByteArrayOutputStream outStream = null;
        String base64 = "";
        try {
            URL url = new URL(urlPath);
            //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
            log.info("图片的url路径为:" + url.toString());
            //打开链接
            HttpURLConnection conn = null;
            conn = (HttpURLConnection) url.openConnection();
            //设置请求方式为"GET"
            conn.setRequestMethod("GET");
            //超时响应时间为5秒
            conn.setConnectTimeout(5 * 1000);
            //通过输入流获取图片数据
            inStream = conn.getInputStream();
            //得到图片的二进制数据，以二进制封装得到数据，具有通用性
            outStream = new ByteArrayOutputStream();
            //创建一个Buffer字符串
            byte[] buffer = new byte[1024];
            //每次读取的字符串长度，如果为-1，代表全部读取完毕
            int len = 0;
            //使用一个输入流从buffer里把数据读取出来
            while ((len = inStream.read(buffer)) != -1) {
                //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
                outStream.write(buffer, 0, len);
            }
            byte[] data = outStream.toByteArray();
            //对字节数组Base64编码
            BASE64Encoder encoder = new BASE64Encoder();
            base64 = encoder.encode(data);
            base64 = base64.replaceAll("\r\n",""); //替换空格
            //base64 = base64.replaceAll("\\+","%2B");
            log.info("网络文件[{}]编码成base64字符串:[{}]" + base64);
            return base64;      //返回Base64编码过的字节数组字符串
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("图片获取失败");
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
                if (outStream != null) {
                    outStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *备用方法2（同第一种方法，只是在此备份记录一下）
     */
    public static String bakMethodBase64(String urlPath) {
        BASE64Encoder encoder = new BASE64Encoder();
        InputStream fin = null;
        BufferedInputStream bin = null;
        ByteArrayOutputStream baos = null;
        BufferedOutputStream bout = null;

        try {
            URL url = new URL(urlPath);
            //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
            log.info("图片的url路径为:" + url.toString());
            //打开链接
            HttpURLConnection conn = null;

            conn = (HttpURLConnection) url.openConnection();
            //设置请求方式为"GET"
            conn.setRequestMethod("GET");
            //超时响应时间为5秒
            conn.setConnectTimeout(5 * 1000);
            //通过输入流获取图片数据
            fin = conn.getInputStream();

            bin = new BufferedInputStream(fin);
            baos = new ByteArrayOutputStream();
            bout = new BufferedOutputStream(baos);
            byte[] buffer = new byte[1024];
            int len = bin.read(buffer);
            while (len != -1) {
                bout.write(buffer, 0, len);
                len = bin.read(buffer);
            }
            //刷新此输出流并强制写出所有缓冲的输出字节
            bout.flush();
            byte[] bytes = baos.toByteArray();
            return encoder.encodeBuffer(bytes).trim();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fin.close();
                bin.close();
                baos.close();
                bout.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    /**
     * 将网络图片编码为base64（使用的是hutool包下的base64进行编码）
     *
     * @param urlPath
     * @return
     * @throws
     */
    public static String encodeImageToString(String urlPath) throws Exception {
        InputStream inStream = null;

        try {
            URL url = new URL(urlPath);
            //将图片文件转化为字节数组字符串，并对其进行Base64编码处理
            log.info("图片的url路径为:" + url.toString());
            //打开链接
            HttpURLConnection conn = null;;
            conn = (HttpURLConnection) url.openConnection();
            //设置请求方式为"GET"
            conn.setRequestMethod("GET");
            //超时响应时间为5秒
            conn.setConnectTimeout(5 * 1000);
            //通过输入流获取图片数据
            inStream = conn.getInputStream();

            ByteArrayOutputStream result = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int length;
            while ((length = inStream.read(buffer)) != -1) {
                result.write(buffer, 0, length);
            }
            String str = result.toString(StandardCharsets.UTF_8.name());
            return str;
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("图片获取失败");
        } finally {
            try {
                //关闭输入流
                if (inStream != null) {
                    inStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



}
